package org.grayrabbit.cms.plugin.loaders;

import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;

import org.grayrabbit.cms.plugin.ModuleDescriptorFactory;
import org.grayrabbit.cms.plugin.Plugin;
import org.grayrabbit.cms.plugin.PluginParseException;
import org.grayrabbit.cms.plugin.impl.StaticPlugin;
import org.grayrabbit.cms.plugin.parsers.DescriptorParser;
import org.grayrabbit.cms.plugin.parsers.DescriptorParserFactory;
import org.grayrabbit.cms.plugin.parsers.XmlDescriptorParserFactory;
import org.grayrabbit.cms.utils.ClassLoaderUtils;


/**
 * @author sys53
 * @version 1.0
 * @created 06-一月-2012 16:15:49
 */
public class SinglePluginLoader implements PluginLoader {
	protected String resource;
	protected InputStream is;
	protected Collection<Plugin> plugins;
	private DescriptorParserFactory descriptorParserFactory = new XmlDescriptorParserFactory();
	public SinglePluginLoader(InputStream inputStream) {
		this.is = inputStream;
	}

	 public SinglePluginLoader(String resource)
	  {
	    this.resource = resource;
	  }

	public Collection<Plugin> loadAllPlugins(ModuleDescriptorFactory moduleDescriptorFactory)  throws PluginParseException{
		if (this.plugins == null)
		      this.plugins = Collections.singleton(loadPlugin(moduleDescriptorFactory));
		    return this.plugins;
	}

	private Plugin loadPlugin(ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException {
		InputStream source = getSource();
		if (source == null)
			throw new PluginParseException("Invalid resource or inputstream specified to load plugins from.");
		Plugin plugin;
		try {
			DescriptorParser parser = this.descriptorParserFactory.getInstance(source);
			plugin = parser.configurePlugin(moduleDescriptorFactory,getNewPlugin());
			if (parser.isSystemPlugin())
				plugin.setSystemPlugin(true);
		} catch (PluginParseException e) {
			throw new PluginParseException("Unable to load plugin resource: "+ this.resource + " - " + e.getMessage(), e);
		}

		return plugin;
	}


	private Plugin getNewPlugin() {
		return new StaticPlugin();
	}

	protected InputStream getSource() {
		if (this.resource == null) {
			return this.is;
		}
		return ClassLoaderUtils.getResourceAsStream(this.resource, getClass());
	}
	
	public void removePlugin(Plugin plugin) {
		throw new UnsupportedOperationException("This PluginLoader does not support removal.");
	}

	public boolean supportsAddition() {
		return false;
	}

	public boolean supportsRemoval() {
		return false;
	}

}